From 1d31fd12c0edaa3d21e2fb53e56ebf613cc9dee5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Wed, 23 Aug 2017 19:53:43 +0200 Subject: [PATCH] babl-icc: create struct for abstracting ICC file access This also makes the ICC parsing re-entrant by getting rid of global variables. --- babl/babl-icc.c | 349 +++++++++++++++++++++++-------------------- babl/babl-internal.h | 9 +- babl/babl-trc.c | 19 ++- babl/babl-trc.h | 22 ++- babl/babl.h | 5 +- 5 files changed, 233 insertions(+), 171 deletions(-) diff --git a/babl/babl-icc.c b/babl/babl-icc.c index 2c6a2a0..69f0df0 100644 --- a/babl/babl-icc.c +++ b/babl/babl-icc.c @@ -21,6 +21,31 @@ #include #include +typedef struct ICC { + char *data; + int length; + + int tags; + int headpos; + int o, no; + int p; + int psize; +} ICC; + +ICC *icc_state_new (char *data, int length, int tags); + +ICC *icc_state_new (char *data, int length, int tags) +{ + ICC *ret = babl_calloc (sizeof (ICC), 1); + ret->data = data; + ret->length = length; + ret->tags = tags; + + return ret; +} + + + #define ICC_HEADER_LEN 128 #define TAG_COUNT_OFF ICC_HEADER_LEN @@ -38,81 +63,81 @@ typedef struct { char str[5]; } sign_t; -#define icc_write(type, offset, value) write_##type(icc,length,offset,value) -#define icc_read(type, offset) read_##type(icc,length,offset) +#define icc_write(type, offset, value) write_##type(state,offset,value) +#define icc_read(type, offset) read_##type(state,offset) -static void write_u8 (char *icc, int length, int offset, uint8_t value) +static void write_u8 (ICC *state, int offset, uint8_t value) { - if (offset < 0 || offset > length) + if (offset < 0 || offset >= state->length) return; - *(uint8_t*) (&icc[offset]) = value; + *(uint8_t*) (&state->data[offset]) = value; } -static void write_s8 (char *icc, int length, int offset, int8_t value) +static void write_s8 (ICC *state, int offset, int8_t value) { - if (offset < 0 || offset > length) + if (offset < 0 || offset >= state->length) return; - *(int8_t*) (&icc[offset]) = value; + *(int8_t*) (&state->data[offset]) = value; } -static int read_u8 (const char *icc, int length, int offset) +static int read_u8 (ICC *state, int offset) { /* all reading functions take both the char *pointer and the length of the * buffer, and all reads thus gets protected by this condition. */ - if (offset < 0 || offset > length) + if (offset < 0 || offset > state->length) return 0; - return *(uint8_t*) (&icc[offset]); + return *(uint8_t*) (&state->data[offset]); } -static int read_s8 (const char *icc, int length, int offset) +static int read_s8 (ICC *state, int offset) { - if (offset < 0 || offset > length) + if (offset < 0 || offset > state->length) return 0; - return *(int8_t*) (&icc[offset]); + return *(int8_t*) (&state->data[offset]); } -static void write_s16 (char *icc, int length, int offset, int16_t value) +static void write_s16 (ICC *state, int offset, int16_t value) { - write_s8 (icc, length, offset + 0, value >> 8); - write_u8 (icc, length, offset + 1, value & 0xff); + write_s8 (state, offset + 0, value >> 8); + write_u8 (state, offset + 1, value & 0xff); } -static int16_t read_s16 (const char *icc, int length, int offset) +static int16_t read_s16 (ICC *state, int offset) { return icc_read (u8, offset + 1) + - (read_s8 (icc, length, offset + 0) << 8); + (read_s8 (state, offset + 0) << 8); //XXX: transform to icc_read macro } -static uint16_t read_u16 (const char *icc, int length, int offset) +static uint16_t read_u16 (ICC *state, int offset) { return icc_read (u8, offset + 1) + (icc_read (u8, offset + 0) << 8); } -static void write_u16 (char *icc, int length, int offset, uint16_t value) +static void write_u16 (ICC *state, int offset, uint16_t value) { - write_u8 (icc, length, offset + 0, value >> 8); - write_u8 (icc, length, offset + 1, value & 0xff); + write_u8 (state, offset + 0, value >> 8); + write_u8 (state, offset + 1, value & 0xff); } -static u8f8_t read_u8f8_ (const char *icc, int length, int offset) +static u8f8_t read_u8f8_ (ICC *state, int offset) { u8f8_t ret ={icc_read (u8, offset), icc_read (u8, offset + 1)}; return ret; } -static s15f16_t read_s15f16_ (const char *icc, int length, int offset) +static s15f16_t read_s15f16_ (ICC *state, int offset) { s15f16_t ret ={icc_read (s16, offset), icc_read (u16, offset + 2)}; return ret; } -static void write_s15f16_ (char *icc, int length, int offset, s15f16_t val) +static void write_s15f16_ (ICC *state, int offset, s15f16_t val) { icc_write (s16, offset, val.integer), icc_write (u16, offset + 2, val.fraction); @@ -136,19 +161,19 @@ static double u8f8_to_d (u8f8_t fix) return fix.integer + fix.fraction / 255.0; } -static void write_s15f16 (char *icc, int length, int offset, double value) +static void write_s15f16 (ICC *state, int offset, double value) { - write_s15f16_ (icc, length, offset, d_to_s15f16 (value)); + write_s15f16_ (state, offset, d_to_s15f16 (value)); } -static double read_s15f16 (const char *icc, int length, int offset) +static double read_s15f16 (ICC *state, int offset) { - return s15f16_to_d (read_s15f16_ (icc, length, offset)); + return s15f16_to_d (read_s15f16_ (state, offset)); } -static double read_u8f8 (const char *icc, int length, int offset) +static double read_u8f8 (ICC *state, int offset) { - return u8f8_to_d (read_u8f8_ (icc, length, offset)); + return u8f8_to_d (read_u8f8_ (state, offset)); } static inline void print_u8f8 (u8f8_t fix) @@ -195,22 +220,19 @@ static inline void print_s15f16 (s15f16_t fix) } } -static void write_u32 (char *icc, - int length, - int offset, - uint32_t value) +static void write_u32 (ICC *state, int offset, uint32_t value) { int i; for (i = 0; i < 4; i ++) { - write_u8 (icc, length, offset + i, + write_u8 (state, offset + i, (value & 0xff000000) >> 24 ); value <<= 8; } } -static uint32_t read_u32 (const char *icc, int length, int offset) +static uint32_t read_u32 (ICC *state, int offset) { return icc_read (u8, offset + 3) + (icc_read (u8, offset + 2) << 8) + @@ -218,8 +240,7 @@ static uint32_t read_u32 (const char *icc, int length, int offset) (icc_read (u8, offset + 0) << 24); } -static sign_t read_sign (const char *icc, int length, - int offset) +static sign_t read_sign (ICC *state, int offset) { sign_t ret; ret.str[0]=icc_read (u8, offset); @@ -230,8 +251,7 @@ static sign_t read_sign (const char *icc, int length, return ret; } -static void write_sign (char *icc, int length, - int offset, char *sign) +static void write_sign (ICC *state, int offset, const char *sign) { int i; for (i = 0; i < 4; i ++) @@ -240,7 +260,7 @@ static void write_sign (char *icc, int length, /* looks up offset and length for a specific icc tag */ -static int icc_tag (const char *icc, int length, +static int icc_tag (ICC *state, const char *tag, int *offset, int *el_length) { int tag_count = icc_read (u32, TAG_COUNT_OFF); @@ -261,11 +281,9 @@ static int icc_tag (const char *icc, int length, return 0; } -static const Babl *babl_trc_from_icc (const char *icc, - int length, - char **error) +static const Babl *babl_trc_from_icc (ICC *state, int offset, + char **error) { - int offset = 0; { int count = icc_read (u32, offset + 8); int i; @@ -280,8 +298,7 @@ static const Babl *babl_trc_from_icc (const char *icc, } else { - return babl_trc_gamma (2.2); - + return babl_trc_gamma (10.0); // XXX: todo implement a curve trc babl type // as well as detect sRGB curve from LUTs @@ -297,15 +314,33 @@ static const Babl *babl_trc_from_icc (const char *icc, return NULL; } +static void icc_allocate_tag (ICC *state, const char *tag, int size) +{ + state->no+=((4-state->o)%4);state->o = state->no;state->psize = size; + icc_write (sign, 128 + 4 + 4 * state->headpos++, tag); + icc_write (u32, 128 + 4 + 4 * state->headpos++, state->o); + icc_write (u32, 128 + 4 + 4 * state->headpos++, size); + state->p = state->no;\ + state->no+=size; +} + +static void icc_duplicate_tag(ICC *state, const char *tag) +{ + icc_write (sign, 128 + 4 + 4 * state->headpos++, tag); + icc_write (u32, 128 + 4 + 4 * state->headpos++, state->p); + icc_write (u32, 128 + 4 + 4 * state->headpos++, state->psize); +} const char *babl_space_rgb_to_icc (const Babl *babl, int *ret_length) { const BablSpace *space = &babl->space; static char icc[8192]; int length=4095; + ICC *state = icc_state_new (icc, length, 10); + icc[length]=0; -#if 1 +#if 0 icc_write (s8, 8,-2); assert (icc_read (s8, 8) == -2); icc_write (s8, 8, 3); // ICC verison @@ -352,113 +387,101 @@ const char *babl_space_rgb_to_icc (const Babl *babl, int *ret_length) icc_write (sign, 36, "acsp"); // changes - { - int headpos = 0; - int tags; - int o, no; - int p = 0; - int psize = 0; - - tags = 10; - no = o = 128 + 4 + 12 * tags; - - icc_write (u32, 128, tags); -#define icc_allocate_tag(tag, size) \ - no+=((4-o)%4);o = no;psize = size;\ - icc_write (sign, 128 + 4 + 4 * headpos++, tag);\ - icc_write (u32, 128 + 4 + 4 * headpos++, o);\ - icc_write (u32, 128 + 4 + 4 * headpos++, size);\ - p = no;\ - no+=size; -#define icc_duplicate_tag(tag) \ - icc_write (sign, 128 + 4 + 4 * headpos++, tag);\ - icc_write (u32, 128 + 4 + 4 * headpos++, p); \ - icc_write (u32, 128 + 4 + 4 * headpos++, psize); - - icc_allocate_tag ("wtpt", 20); - icc_write (sign,o, "XYZ "); - icc_write (u32, o + 4, 0); - icc_write (s15f16, o + 8, space->whitepoint[0]); - icc_write (s15f16, o + 12, space->whitepoint[1]); - icc_write (s15f16, o + 16, space->whitepoint[2]); - - icc_allocate_tag ("rXYZ", 20); - icc_write (sign,o, "XYZ "); - icc_write (u32, o + 4, 0); - icc_write (s15f16, o + 8, space->RGBtoXYZ[0]); - icc_write (s15f16, o + 12, space->RGBtoXYZ[3]); - icc_write (s15f16, o + 16, space->RGBtoXYZ[6]); - - icc_allocate_tag ("gXYZ", 20); - icc_write (sign,o, "XYZ "); - icc_write (u32, o + 4, 0); - icc_write (s15f16, o + 8, space->RGBtoXYZ[1]); - icc_write (s15f16, o + 12, space->RGBtoXYZ[4]); - icc_write (s15f16, o + 16, space->RGBtoXYZ[7]); - - icc_allocate_tag ("bXYZ", 20); - icc_write (sign,o, "XYZ "); - icc_write (u32, o + 4, 0); - icc_write (s15f16, o + 8, space->RGBtoXYZ[2]); - icc_write (s15f16, o + 12, space->RGBtoXYZ[5]); - icc_write (s15f16, o + 16, space->RGBtoXYZ[8]); - - icc_allocate_tag ("rTRC", 14); - icc_write (sign,o, "curv"); - icc_write (u32, o + 4, 0); - icc_write (u32, o + 8, 1); - icc_write (u16, o + 12, 334); + state->tags = 10; /* note: we could reserve a couple of spots and + still use a very simple allocator and + still be valid - albeit with tiny waste of + space. + */ + state->no = state->o = 128 + 4 + 12 * state->tags; + + icc_write (u32, 128, state->tags); + + icc_allocate_tag (state, "wtpt", 20); + icc_write (sign, state->o, "XYZ "); + icc_write (u32, state->o + 4, 0); + icc_write (s15f16, state->o + 8, space->whitepoint[0]); + icc_write (s15f16, state->o + 12, space->whitepoint[1]); + icc_write (s15f16, state->o + 16, space->whitepoint[2]); + + icc_allocate_tag (state, "rXYZ", 20); + icc_write (sign, state->o, "XYZ "); + icc_write (u32, state->o + 4, 0); + icc_write (s15f16, state->o + 8, space->RGBtoXYZ[0]); + icc_write (s15f16, state->o + 12, space->RGBtoXYZ[3]); + icc_write (s15f16, state->o + 16, space->RGBtoXYZ[6]); + + icc_allocate_tag (state, "gXYZ", 20); + icc_write (sign, state->o, "XYZ "); + icc_write (u32, state->o + 4, 0); + icc_write (s15f16, state->o + 8, space->RGBtoXYZ[1]); + icc_write (s15f16, state->o + 12, space->RGBtoXYZ[4]); + icc_write (s15f16, state->o + 16, space->RGBtoXYZ[7]); + + icc_allocate_tag (state, "bXYZ", 20); + icc_write (sign, state->o, "XYZ "); + icc_write (u32, state->o + 4, 0); + icc_write (s15f16, state->o + 8, space->RGBtoXYZ[2]); + icc_write (s15f16, state->o + 12, space->RGBtoXYZ[5]); + icc_write (s15f16, state->o + 16, space->RGBtoXYZ[8]); + + icc_allocate_tag (state, "rTRC", 14); + icc_write (sign, state->o, "curv"); + icc_write (u32, state->o + 4, 0); + icc_write (u32, state->o + 8, 1); + icc_write (u16, state->o + 12, 334); if (space->trc[0] == space->trc[1] && space->trc[0] == space->trc[2]) { - icc_duplicate_tag ("gTRC"); - icc_duplicate_tag ("bTRC"); + icc_duplicate_tag (state, "gTRC"); + icc_duplicate_tag (state, "bTRC"); } else { - icc_allocate_tag ("gTRC", 14); - icc_write (sign,o, "curv"); - icc_write (u32, o + 4, 0); - icc_write (u32, o + 8, 1); /* forcing a linear curve */ - icc_allocate_tag ("bTRC", 14); - icc_write (sign,o, "curv"); - icc_write (u32, o + 4, 0); - icc_write (u32, o + 8, 1); /* forcing a linear curve */ + icc_allocate_tag (state, "gTRC", 14); + icc_write (sign, state->o, "curv"); + icc_write (u32, state->o + 4, 0); + icc_write (u32, state->o + 8, 1); /* forcing a linear curve */ + icc_allocate_tag (state, "bTRC", 14); + icc_write (sign, state->o, "curv"); + icc_write (u32, state->o + 4, 0); + icc_write (u32, state->o + 8, 1); /* forcing a linear curve */ } { char str[128]; int i; sprintf (str, "babl"); - icc_allocate_tag("desc", 100 + strlen (str) + 1); - icc_write (sign,o,"desc"); - icc_write (u32, o + 4, 0); - icc_write (u32, o + 8, strlen(str)); + icc_allocate_tag(state, "desc", 100 + strlen (str) + 1); + icc_write (sign, state->o,"desc"); + icc_write (u32, state->o + 4, 0); + icc_write (u32, state->o + 8, strlen(str)); for (i = 0; str[i]; i++) - icc_write (u8, o + 12 + i, str[i]); + icc_write (u8, state->o + 12 + i, str[i]); - icc_duplicate_tag ("dmnd"); + icc_duplicate_tag (state, "dmnd"); } { char str[128]; int i; sprintf (str, "CC0/public domain"); - icc_allocate_tag("cprt", 8 + strlen (str) + 1); - icc_write (sign,o, "text"); - icc_write (u32, o + 4, 0); + icc_allocate_tag(state, "cprt", 8 + strlen (str) + 1); + icc_write (sign, state->o, "text"); + icc_write (u32, state->o + 4, 0); for (i = 0; str[i]; i++) - icc_write (u8, o + 8 + i, str[i]); + icc_write (u8, state->o + 8 + i, str[i]); } - icc_write (u32, 0, no + 3); - length = no + 3; + icc_write (u32, 0, state->no + 3); + length = state->no + 3; } if (ret_length) *ret_length = length; + + babl_free (state); return icc; } @@ -467,6 +490,8 @@ babl_space_rgb_icc (const char *icc, int length, char **error) { + ICC *state = icc_state_new ((char*)icc, length, 0); + int profile_size = icc_read (u32, 0); int icc_ver_major = icc_read (u8, 8); const Babl *trc_red = NULL; @@ -477,54 +502,56 @@ babl_space_rgb_icc (const char *icc, if (profile_size != length) { *error = "icc profile length inconsistency"; - return NULL; } - if (icc_ver_major > 2) + else if (icc_ver_major > 2) { *error = "only ICC v2 profiles supported"; - return NULL; } + else + { profile_class = icc_read (sign, 12); if (strcmp (profile_class.str, "mntr")) - { *error = "not a monitor-class profile"; - return NULL; - } + else + { color_space = icc_read (sign, 16); if (strcmp (color_space.str, "RGB ")) - { *error = "not defining an RGB space"; - return NULL; } + } + { int offset, element_size; - if (icc_tag (icc, length, "rTRC", &offset, &element_size)) + if (!*error && icc_tag (state, "rTRC", &offset, &element_size)) { - trc_red = babl_trc_from_icc (icc + offset, element_size, error); - if (*error) return NULL; + trc_red = babl_trc_from_icc (state, offset, error); } - if (icc_tag (icc, length, "gTRC", &offset, &element_size)) + if (!*error && icc_tag (state, "gTRC", &offset, &element_size)) { - trc_green = babl_trc_from_icc (icc + offset, element_size, error); - if (*error) return NULL; + trc_green = babl_trc_from_icc (state, offset, error); } - if (icc_tag (icc, length, "bTRC", &offset, &element_size)) + if (!*error && icc_tag (state, "bTRC", &offset, &element_size)) { - trc_blue = babl_trc_from_icc (icc + offset, element_size, error); - if (*error) return NULL; + trc_blue = babl_trc_from_icc (state, offset, error); } } - if (!trc_red || !trc_green || !trc_blue) + + if (!*error && (!trc_red || !trc_green || !trc_blue)) { *error = "missing TRCs"; - return NULL; } - if (icc_tag (icc, length, "rXYZ", NULL, NULL) && - icc_tag (icc, length, "gXYZ", NULL, NULL) && - icc_tag (icc, length, "bXYZ", NULL, NULL) && - icc_tag (icc, length, "wtpt", NULL, NULL)) + if (*error) + { + babl_free (state); + return NULL; + } + + if (icc_tag (state, "rXYZ", NULL, NULL) && + icc_tag (state, "gXYZ", NULL, NULL) && + icc_tag (state, "bXYZ", NULL, NULL) && + icc_tag (state, "wtpt", NULL, NULL)) { int offset, element_size; double rx, gx, bx; @@ -533,22 +560,24 @@ babl_space_rgb_icc (const char *icc, double wX, wY, wZ; - icc_tag (icc, length, "rXYZ", &offset, &element_size); + icc_tag (state, "rXYZ", &offset, &element_size); rx = icc_read (s15f16, offset + 8 + 4 * 0); ry = icc_read (s15f16, offset + 8 + 4 * 1); rz = icc_read (s15f16, offset + 8 + 4 * 2); - icc_tag (icc, length, "gXYZ", &offset, &element_size); + icc_tag (state, "gXYZ", &offset, &element_size); gx = icc_read (s15f16, offset + 8 + 4 * 0); gy = icc_read (s15f16, offset + 8 + 4 * 1); gz = icc_read (s15f16, offset + 8 + 4 * 2); - icc_tag (icc, length, "bXYZ", &offset, &element_size); + icc_tag (state, "bXYZ", &offset, &element_size); bx = icc_read (s15f16, offset + 8 + 4 * 0); by = icc_read (s15f16, offset + 8 + 4 * 1); bz = icc_read (s15f16, offset + 8 + 4 * 2); - icc_tag (icc, length, "wtpt", &offset, &element_size); + icc_tag (state, "wtpt", &offset, &element_size); wX = icc_read (s15f16, offset + 8); wY = icc_read (s15f16, offset + 8 + 4); wZ = icc_read (s15f16, offset + 8 + 4 * 2); + + babl_free (state); return babl_space_rgb_matrix (NULL, wX, wY, wZ, @@ -557,14 +586,14 @@ babl_space_rgb_icc (const char *icc, rz, gz, bz, trc_red, trc_green, trc_blue); } - else if (icc_tag (icc, length, "chrm", NULL, NULL) && - icc_tag (icc, length, "wtpt", NULL, NULL)) + else if (icc_tag (state, "chrm", NULL, NULL) && + icc_tag (state, "wtpt", NULL, NULL)) { int offset, element_size; double red_x, red_y, green_x, green_y, blue_x, blue_y; int channels, phosporant; - icc_tag (icc, length, "chrm", &offset, &element_size); + icc_tag (state, "chrm", &offset, &element_size); channels = icc_read (u16, offset + 8); phosporant = icc_read (u16, offset + 10); @@ -586,11 +615,12 @@ babl_space_rgb_icc (const char *icc, blue_x = icc_read (s15f16, offset + 28); blue_y = icc_read (s15f16, offset + 28 + 4); - icc_tag (icc, length, "wtpt", &offset, &element_size); + icc_tag (state, "wtpt", &offset, &element_size); { double wX = icc_read (s15f16, offset + 8); double wY = icc_read (s15f16, offset + 8 + 4); double wZ = icc_read (s15f16, offset + 8 + 4 * 2); + babl_free (state); return babl_space_rgb_chromaticities (NULL, wX / (wX + wY + wZ), @@ -604,5 +634,6 @@ babl_space_rgb_icc (const char *icc, } *error = "didnt find RGB primaries"; + babl_free (state); return NULL; } diff --git a/babl/babl-internal.h b/babl/babl-internal.h index b9c287e..4232710 100644 --- a/babl/babl-internal.h +++ b/babl/babl-internal.h @@ -355,9 +355,12 @@ void babl_space_get_chromaticities (const Babl *space, double *gx, double *gy, double *bx, double *by); -const Babl * babl_trc_new (const char *name, - BablTRCType type, - double gamma); +const Babl * +babl_trc_new (const char *name, + BablTRCType type, + double gamma, + int n_lut, + float *lut); /** * babl_trc_from_linear: diff --git a/babl/babl-trc.c b/babl/babl-trc.c index 9f8cb58..5719e03 100644 --- a/babl/babl-trc.c +++ b/babl/babl-trc.c @@ -40,7 +40,9 @@ babl_trc (const char *name) const Babl * babl_trc_new (const char *name, BablTRCType type, - double gamma) + double gamma, + int n_lut, + float *lut) { int i=0; static BablTRC trc; @@ -74,6 +76,11 @@ babl_trc_new (const char *name, return (Babl*)&trc_db[i]; } +const Babl * babl_trc_lut (const char *name, int n, float *entries) +{ + return babl_trc_new (name, BABL_TRC_LUT, 0, n, entries); +} + void babl_trc_class_for_each (BablEachFunction each_fun, void *user_data) @@ -90,24 +97,24 @@ babl_trc_gamma (double gamma) char name[32]; int i; if (fabs (gamma - 1.0) < 0.0001) - return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0); + return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL); sprintf (name, "%.6f", gamma); for (i = 0; name[i]; i++) if (name[i] == ',') name[i] = '.'; while (name[strlen(name)-1]=='0') name[strlen(name)-1]='\0'; - return babl_trc_new (name, BABL_TRC_GAMMA, gamma); + return babl_trc_new (name, BABL_TRC_GAMMA, gamma, 0, NULL); } + void babl_trc_class_init (void) { - /* we register sRGB first so that lookups for it is fastest */ - babl_trc_new ("sRGB", BABL_TRC_SRGB, 2.2); + babl_trc_new ("sRGB", BABL_TRC_SRGB, 2.2, 0, NULL); babl_trc_gamma (2.2); babl_trc_gamma (1.8); babl_trc_gamma (1.0); - babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0); + babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL); } double babl_trc_from_linear (const Babl *trc_, double value) diff --git a/babl/babl-trc.h b/babl/babl-trc.h index fd7a0c5..c762810 100644 --- a/babl/babl-trc.h +++ b/babl/babl-trc.h @@ -27,7 +27,8 @@ BABL_CLASS_DECLARE (trc); typedef enum {BABL_TRC_LINEAR, BABL_TRC_GAMMA, - BABL_TRC_SRGB} BablTRCType; + BABL_TRC_SRGB, + BABL_TRC_LUT} BablTRCType; typedef struct { @@ -35,9 +36,20 @@ typedef struct BablTRCType type; double gamma; char name[128]; - + float *lut; + int lut_size; } BablTRC; +static inline double babl_trc_lut_from_linear (const Babl *trc_, double value) +{ + return 0; +} + +static inline double babl_trc_lut_to_linear (const Babl *trc_, double value) +{ + return 0; +} + static inline double _babl_trc_from_linear (const Babl *trc_, double value) { BablTRC *trc = (void*)trc_; @@ -49,6 +61,8 @@ static inline double _babl_trc_from_linear (const Babl *trc_, double value) return pow (value, 1.0/trc->gamma); case BABL_TRC_SRGB: return babl_linear_to_gamma_2_2 (value); + case BABL_TRC_LUT: + return babl_trc_lut_from_linear (trc_, value); } return value; } @@ -64,6 +78,8 @@ static inline double _babl_trc_to_linear (const Babl *trc_, double value) return pow (value, trc->gamma); case BABL_TRC_SRGB: return babl_gamma_2_2_to_linear (value); + case BABL_TRC_LUT: + return babl_trc_lut_to_linear (trc_, value); } return value; } @@ -76,6 +92,7 @@ static inline float _babl_trc_from_linearf (const Babl *trc_, float value) case BABL_TRC_LINEAR: return value; case BABL_TRC_GAMMA: return powf (value, 1.0f/trc->gamma); case BABL_TRC_SRGB: return babl_linear_to_gamma_2_2f (value); + case BABL_TRC_LUT: return babl_trc_lut_from_linear (trc_, value); } return value; } @@ -88,6 +105,7 @@ static inline float _babl_trc_to_linearf (const Babl *trc_, float value) case BABL_TRC_LINEAR: return value; case BABL_TRC_GAMMA: return powf (value, trc->gamma); case BABL_TRC_SRGB: return babl_gamma_2_2_to_linearf (value); + case BABL_TRC_LUT: return babl_trc_lut_to_linear (trc_, value); } return value; } diff --git a/babl/babl.h b/babl/babl.h index b601615..e05ea49 100644 --- a/babl/babl.h +++ b/babl/babl.h @@ -91,10 +91,13 @@ const Babl * babl_trc (const char *name); /** * babl_trc_gamma: * - * Creates a Babl TRC for a specific gamma value. + * Creates a Babl TRC for a specific gamma value, it will be given + * a name */ const Babl * babl_trc_gamma (double gamma); +const Babl * babl_trc_lut (const char *name, int n, float *entries); + /** * babl_space: -- 2.30.2